package com.sen.ssp.common.interceptors;

import java.util.Locale;
import java.util.Map;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.ServletActionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.util.LocalizedTextUtil;

/**
 * 自定义i18n国际化拦截器
 * 
 * @author sen
 */
public class I18nBeforeInterceptor extends BaseInterceptor {

	private static final long serialVersionUID = 3239103680144227783L;
	
	protected static Logger LOG = LoggerFactory.getLogger(I18nBeforeInterceptor.class);

    public static final String DEFAULT_SESSION_ATTRIBUTE = "WW_TRANS_I18N_LOCALE";
    public static final String DEFAULT_PARAMETER = "request_locale";
    public static final String DEFAULT_COOKIE_NAME = "cookie_i18n_locale";

    protected String attributeName = DEFAULT_SESSION_ATTRIBUTE;
    protected String parameterName = DEFAULT_PARAMETER;
    protected String lanCookieName = DEFAULT_COOKIE_NAME;

    public I18nBeforeInterceptor() {
        if (LOG.isInfoEnabled()) {
            LOG.info("new I18nBeforeInterceptor()");
        }
    }

    public void setParameterName(String parameterName) {
        this.parameterName = parameterName;
    }

    public void setAttributeName(String attributeName) {
        this.attributeName = attributeName;
    }
    
    public void setLanCookieName(String lanCookieName) {
    	this.lanCookieName = lanCookieName;
    }

    public String intercept(ActionInvocation invocation) throws Exception {
        if (LOG.isDebugEnabled()) {
            LOG.debug("intercept '"
                    + invocation.getProxy().getNamespace() + "/"
                    + invocation.getProxy().getActionName() + "' { ");
        }
        
        //get requested locale
        Map<String, Object> params = invocation.getInvocationContext().getParameters();
        Object requested_locale = findLocaleParameter(params, parameterName);

        //save it in session
        Map<String, Object> session = invocation.getInvocationContext().getSession();
        
        if (session != null) {
            synchronized (session) {
            	Cookie cookie = getLocaleCookie();
            	if (requested_locale != null) {
            		Locale locale = (requested_locale instanceof Locale) ?
                            (Locale) requested_locale : LocalizedTextUtil.localeFromString(requested_locale.toString(), null);
                    if (locale != null && LOG.isDebugEnabled()) {
                        LOG.debug("put request local to cookie=" + locale);
                    }
                    setLocaleCookie(cookie, requested_locale.toString());
                } else if (cookie != null) {
                	requested_locale = cookie.getValue();
					if (LOG.isDebugEnabled()) {
						LOG.debug("put cookie local to request_params=" + requested_locale);
					}
					params.put(parameterName, requested_locale);
                }
            }
        }

        final String result = invocation.invoke();

        if (LOG.isDebugEnabled()) {
            LOG.debug("intercept } ");
        }

        return result;
    }

    private Object findLocaleParameter(Map<String, Object> params, String parameterName) {
        Object requested_locale = params.remove(parameterName);
        if (requested_locale != null && requested_locale.getClass().isArray()
                && ((Object[]) requested_locale).length == 1) {
            requested_locale = ((Object[]) requested_locale)[0];

            if (LOG.isDebugEnabled()) {
                LOG.debug("requested_locale=" + requested_locale);
            }
        }
        return requested_locale;
    }
    
	private Cookie getLocaleCookie() {
		HttpServletRequest request = ServletActionContext.getRequest();
		Cookie cookies[] = request.getCookies();
		if (cookies != null) {
			for (int a = 0; a < cookies.length; a++) {
				if (cookies[a].getName().equals(lanCookieName)) {
					return cookies[a];
				}
			}
		}
		return null;
	}
	
	private void setLocaleCookie(Cookie cookie, String lan) {
		HttpServletResponse response = ServletActionContext.getResponse();
		if (cookie == null) {
			cookie = new Cookie(lanCookieName, lan);
		} else {
			cookie.setValue(lan);
		}
		cookie.setMaxAge(Integer.MAX_VALUE);
		cookie.setPath("/");
		response.addCookie(cookie);
	}

}
